#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <arpa/inet.h>
#include <unistd.h>


#define SERVER_IP   "192.168.231.130"           //ubuntu 本地的ip地址
#define SERVER_PORT 5001                        //ubuntu 本地的端口号


/***建立服务端***/
/*
1、建立套接字---------socket()
2、绑定本地IP和端口号--bind()
3、监听--------------listen()
4、接收客户端---------accept()
5、和客户端进行间通信--recv()/read(), send()/write()
6、关闭套接字---------close()
*/
int main(void)
{
    int socket_fd = 0;

    socket_fd = socket(AF_INET, SOCK_STREAM, 0);        //创建套接字
    if(-1 == socket_fd)
    {
        perror("socket error");
        return -1;
    }

    struct sockaddr_in server_addr;                     //定义一个IPv4结构体变量，初始化自己的（服务端）的ip地址、端口号
    server_addr.sin_family = AF_INET;                   //IPv4
    server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); //ip地址：本地ip---->网络ip
    server_addr.sin_port = htons(SERVER_PORT);          //端口号：本地端口号---->网络端口号

    int ret = 0;                                        //绑定本地的ip地址和端口号
    ret = bind(socket_fd, (const struct sockaddr *)&server_addr, sizeof(struct sockaddr_in));
    if(-1 == ret)
    {
        perror("bind error");
        return -1;
    }

    char *host_ip = inet_ntoa(server_addr.sin_addr);    //ip地址：网络ip---->本地ip
    uint16_t host_port = ntohs(server_addr.sin_port);   //端口号：网络端口号---->本地端口号
    printf("Successfully bind to local: [%s][%d]\n", host_ip, host_port);

    ret = listen(socket_fd, 20);                        //监听
    if(-1 == ret)
    {
        perror("listen error");
        return -1;
    }
    printf("listening......\n");

    int client_fd = 0;
    struct sockaddr_in client_addr = { 0 };                 //定义一个IPv4结构体变量，存储客户端的ip地址、端口号
    socklen_t client_addr_len = sizeof(struct sockaddr_in);
    client_fd = accept(socket_fd, (struct sockaddr*)&client_addr, &client_addr_len);       //阻塞等待新的客户端连接
    if(-1 == client_fd)
    {
        perror("accept error");
        return -1;
    }

    char *client_ip = inet_ntoa(client_addr.sin_addr);      //ip地址：网络ip---->本地ip
    uint16_t client_port = ntohs(client_addr.sin_port);     //端口号：网络端口号---->本地端口号

    printf("The client is successfully connected: [%s][%d]\n", client_ip, client_port);

    char buf[1024] = { 0 };

    pid_t pid = fork();                                   //创建子进程，返回值是子进程的pid
    if(-1 == pid)
    {
        perror("fork error");
        return -1;
    }

    if(pid > 0)                                         //该进程为父进程，用于向客户端发送消息
    {
        while(true)
        {
            memset(buf, 0, sizeof(buf));
            printf("Send the message to the client: ");
            fgets(buf, sizeof(buf), stdin);
            size_t len = strlen(buf);
            ret = send(client_fd, buf, len, 0);         //向客户端发送消息
            if(-1 == ret)
            {
                perror("recv error");
                return -1;
            }
        }
    }
    else                                                 //该进程为子进程，用于接收客户端发送的消息
    {
        while(true)
        {
            memset(buf, 0, sizeof(buf));
            ret = recv(client_fd, buf, sizeof(buf), 0);         //接收客户端的消息
            if(-1 == ret)
            {
                perror("recv error");
                return -1;
            }

            printf("Received the message sent by the client: %s", buf);
        }
    }
    

    ret = close(socket_fd);
    if(-1 == ret)
    {
        perror("close error");
        return -1;
    }
    

    return 0;
}